/*
	File:		MainMenuState.cpp
	Course:		SGD 1301
	Author:		dmonroe
	Purpose:	CMainMenuState class handles the main menu
*/

#include "MainMenuState.h"

#include "../SGD Wrappers/CSGD_DirectInput.h"
#include "../SGD Wrappers/CSGD_Direct3D.h"
#include "../SGD Wrappers/CSGD_TextureManager.h"

#include "Game.h"
#include "GameplayState.h"
#include "CreditState.h"
#include "OptionState.h"
#include "HowToPlayState.h"
#include "CharacterSelectionState.h"
#include "BitmapFont.h"

#include <cassert>


struct SMenuItem
{
public:
	int posX,posY;
	float scale;
	TCHAR* text;
	SMenuItem(TCHAR* _text,int _posX,int _posY,float _scale)
	{
		text = _text;
		posX=_posX;
		posY=_posY;
		scale = _scale;
	}
};

struct SBackgroundItem
{
public:
	int posX,posY,startY,startX;
	float scale;
	float sinWave;
	SBackgroundItem(int _posX,int _posY,float _scale)
	{
		startX = _posX;
		startY = _posY;
		posX=_posX;
		posY=_posY;
		scale = _scale;
		sinWave = 0;
	}
	void update( float fElapsedTime )
	{
		sinWave+=3.1415f* fElapsedTime ;
		posX+=(int)(100* fElapsedTime) ;//move left;
		posY = startY + (int)(sin(sinWave)*50);
		if(posX>CGame::GetInstance()->GetWidth())
			posX=-64;
	}
};


////////////////////////////////////////////////////////////
// SINGLETON!
/*static*/ CMainMenuState* CMainMenuState::GetInstance( void )
{
	// Static local object
	static CMainMenuState s_Instance;

	return &s_Instance;
}


////////////////////////////////////////////////////////////
// CONSTRUCTOR
CMainMenuState::CMainMenuState(void)
{
	m_pDI		= nullptr;
	m_pTM		= nullptr;
	m_pFont		= nullptr;
	
	int space = 50;
	int start = 200;
	int current = start;
	
	menuVector.push_back(new SMenuItem(_T("Play Game"),100, current+=space, 1.0f));
	menuVector.push_back(new SMenuItem(_T("How To Play"),100, current+=space, 1.0f));
	menuVector.push_back(new SMenuItem(_T("Option"),100, current+=space, 1.0f));
	menuVector.push_back(new SMenuItem(_T("Credits"),100, current+=space, 1.0f));
	menuVector.push_back(new SMenuItem(_T("Exit"),100, current+=space, 1.0f));
	
	m_nCursorImageID	= -1;
	m_nShipImageID	= -1;
	
	m_nCursorPos		= 0;

}


////////////////////////////////////////////////////////////
// DESTRUCTOR
CMainMenuState::~CMainMenuState(void)
{
	for(unsigned int i = 0; i < menuVector.size(); ++i)
		delete menuVector[i];
	menuVector.clear();
}


////////////////////////////////////////////////////////////
// Enter				- load resources
/*virtual*/ void CMainMenuState::Enter( void )
{
	// Store wrappers
	m_pDI		= CSGD_DirectInput::GetInstance();
	m_pTM		= CSGD_TextureManager::GetInstance();
	m_pFont		= CGame::GetInstance()->GetFont();
	
	// Load assets
	m_nCursorImageID	= m_pTM->LoadTexture( 
							_T("resource/graphics/PN_MenuCursor.png") );
	m_nShipImageID		= m_pTM->LoadTexture( 
							_T("resource/graphics/PN_ship4.png") );
	
	shipBI = new SBackgroundItem(-64,100,64/512.0f);

	// Set other members
	m_nCursorPos		= 0;
	m_nMenuSize			= menuVector.size();
}

////////////////////////////////////////////////////////////
// Exit					- unload resources
/*virtual*/ void CMainMenuState::Exit( void )
{
	// Unload the assets
	if( m_nCursorImageID != -1 )
	{
		m_pTM->UnloadTexture( m_nCursorImageID );
		m_nCursorImageID = -1;
	}	// Unload the assets
	if( m_nShipImageID != -1 )
	{
		m_pTM->UnloadTexture( m_nShipImageID );
		m_nShipImageID = -1;
	}

	delete shipBI;

	// Reset the wrappers to null
	m_pDI		= nullptr;
	m_pTM		= nullptr;
	m_pFont		= nullptr;
}

////////////////////////////////////////////////////////////
// Input			- handle user input
/*virtual*/ bool CMainMenuState::Input( void )
{
	if( m_pDI->KeyPressed( DIK_UP ) )
	{
		--m_nCursorPos;
		if(m_nCursorPos<0)
			m_nCursorPos = m_nMenuSize - 1;
	}
	else if( m_pDI->KeyPressed( DIK_DOWN ) )
	{
		++m_nCursorPos;
		if(m_nCursorPos == m_nMenuSize)
			m_nCursorPos = 0;
	}
	if( m_pDI->KeyPressed( DIK_ESCAPE ) )
	{
		if(m_nCursorPos == m_nMenuSize - 1)//Pressed escaped when it was already on escape
			return false;
		m_nCursorPos = m_nMenuSize -1;
	}

	if( m_pDI->KeyPressed( DIK_RETURN ) )
	{
		switch( m_nCursorPos )
		{
		case 0:		// Play Game
			{
				CGame::GetInstance()->PushState( CCharacterSelection::GetInstance() );
				return true;
			}
			break;
		case 1:		// How To Play
			{
				CGame::GetInstance()->PushState( CHowToPlayState::GetInstance() );
				return true;
			}
			break;
		case 2:		// Option
			{
				CGame::GetInstance()->PushState( COptionState::GetInstance() );
				return true;
			}
			break;
		case 3:		// Credits
			{
				CGame::GetInstance()->PushState( CCreditState::GetInstance() );
				return true;
			}
			break;
		case 4:		// Exit
			{
				return false;
			}
			break;
		}
	}


	return true;
}				

////////////////////////////////////////////////////////////
// Update			- update game entities
/*virtual*/ void CMainMenuState::Update( float fElapsedTime )
{
	sinWave+=3.1415f*fElapsedTime;
	shipBI->update(fElapsedTime);
}

////////////////////////////////////////////////////////////
// Render			- render game entities
/*virtual*/ void CMainMenuState::Render( void )
{
	m_pTM->Draw(m_nShipImageID,shipBI->posX,shipBI->posY,shipBI->scale,shipBI->scale,nullptr,256,256,3.1415f/2);
	// Render the menu
	m_pFont->Draw( _T("I Made A Game With Space Ship"), 100, 100, 1.0f, D3DCOLOR_ARGB( 255, 255, 255, 255 ) );
	
	for(unsigned int i = 0; i < menuVector.size(); ++i)
	{
		D3DCOLOR color = D3DCOLOR_ARGB( 255, 255, 255, 255 );
		float scale = menuVector[i]->scale;
		if(m_nCursorPos==i)
		{
			color = D3DCOLOR_ARGB( (int)(sin(sinWave)*255), 255, 255, 255 );
			scale += (sin(sinWave)*0.1f);
		}
		m_pFont->Draw(menuVector[i]->text,menuVector[i]->posX,menuVector[i]->posY,scale, color);
	}	
	int nCursorX = menuVector[m_nCursorPos]->posX - 24;
	int nCursorY = menuVector[m_nCursorPos]->posY + 8;
	m_pTM->Draw( m_nCursorImageID, nCursorX, nCursorY);
}
	